package com.macro.mall.tiny.modules.ums.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.macro.mall.tiny.common.api.CommonResult;
import com.macro.mall.tiny.component.sms.SmsSender;
import com.macro.mall.tiny.component.tencent.CosComponent;
import com.macro.mall.tiny.component.wx.WxClient;
import com.macro.mall.tiny.component.wx.entity.bo.WxBO;
import com.macro.mall.tiny.modules.ums.model.UmsMember;
import com.macro.mall.tiny.modules.ums.mapper.UmsMemberMapper;
import com.macro.mall.tiny.modules.ums.service.UmsMemberCacheService;
import com.macro.mall.tiny.modules.ums.service.UmsMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.macro.mall.tiny.modules.ums.vo.LoginVO;
import com.macro.mall.tiny.security.util.JwtTokenUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

/**
 * <p>
 * 小程序用户表 服务实现类
 * </p>
 *
 * @author tyrone
 * @since 2024-10-14
 */
@Service
public class UmsMemberServiceImpl extends ServiceImpl<UmsMemberMapper, UmsMember> implements UmsMemberService {
    private static final Logger LOGGER = LoggerFactory.getLogger(UmsMemberServiceImpl.class);
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private UmsMemberMapper memberMapper;

    @Autowired
    private UmsMemberCacheService memberCacheService;

    @Value("${redis.key.authCode}")
    private String REDIS_KEY_PREFIX_AUTH_CODE;
    @Value("${redis.expire.authCode}")
    private Long AUTH_CODE_EXPIRE_SECONDS;

    @Autowired
    private WxClient wxClient;
    @Autowired
    private UmsMemberMapper umsMemberMapper;
    @Autowired
    private UmsMemberCacheServiceImpl umsMemberCacheServiceImpl;

    @Autowired
    private SmsSender smsSender;

    @Autowired
    private CosComponent cosComponent;

    @Override
    public CommonResult fillInfo(UmsMember umsMember) {
        if (umsMember.getCode() != null) {
            WxBO userPhone = wxClient.getUserPhone(umsMember.getCode());
            if (!userPhone.getSuccess()) {
                return CommonResult.failed(userPhone.getErrorMsg());
            }
            umsMember.setPhone(userPhone.getPurePhone());
            umsMember.setStatus(1);
            umsMember.setBalance(null);
        }


        umsMemberMapper.updateById(umsMember);
//        umsMemberCacheServiceImpl.delMember(umsMember.getId());

        return CommonResult.success(getUmsMemberById(umsMember.getId()));
    }

    @Override
    public UmsMember getUmsMemberByOpenId(String openId) {
        return umsMemberMapper.selectOne(new QueryWrapper<>(new UmsMember()).eq("open_id", openId));
    }

    @Override
    public CommonResult<LoginVO> check(String jsCode) {
        WxBO sessionInfo = wxClient.getSessionInfo(jsCode);
        if (sessionInfo == null || !sessionInfo.getSuccess() || StringUtils.isEmpty(sessionInfo.getOpenid())) {
            //获取openidFail
            return CommonResult.failed(sessionInfo.getErrorMsg());
        }

        UmsMember um = memberMapper.selectOne(new QueryWrapper<UmsMember>().eq("open_id", sessionInfo.getOpenid()));

        if (um == null) {
            register(sessionInfo.getOpenid());
            LoginVO loginVO = new LoginVO();
            loginVO.setWxInfo(sessionInfo);
            um = memberMapper.selectOne(new QueryWrapper<UmsMember>().eq("open_id", sessionInfo.getOpenid()));
        }
        if (um.getVipExpireTime() != null && um.getVipExpireTime().before(new Date()) && um.getVip() == 1) {
            um.setVip(0);
            um.setVipExpireTime(null);
            memberMapper.update(um, new UpdateWrapper<UmsMember>().eq("id", um.getId()));
//            memberCacheService.delMember(um.getId());
        }
        String token = jwtTokenUtil.generateMemberToken(um);

        return CommonResult.success(new LoginVO(sessionInfo, um, token));
    }

    @Override
    public UmsMember getUmsMemberById(Long memberId) {
//        UmsMember member = memberCacheService.getMember(memberId);
//        if (member != null) return member;
        UmsMember um = memberMapper.selectOne(new QueryWrapper<UmsMember>().eq("id", memberId));
        if (um != null) {
//            memberCacheService.setMember(um);
            return um;
        }
        return null;
    }

    @Override
    public void register(String openId) {
        //没有该用户进行添加操作
        UmsMember umsMember = new UmsMember();
        umsMember.setOpenId(openId);
        umsMember.setCreateTime(new Date());
        umsMember.setStatus(0);
        umsMember.setVip(0);
        umsMember.setIcon("https://document-1328890941.cos.ap-shanghai.myqcloud.com/member/icon/default.jpg");
        umsMember.setNickname("用户" + RandomUtil.randomString(6));
        memberMapper.insert(umsMember);
    }


    @Override
    public String generateauthcode(String telephone, String openId) {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            sb.append(random.nextInt(10));
        }
        String msgCode = sb.toString();
        smsSender.sendMessage(telephone + ":" + msgCode);
        memberCacheService.setAuthCode(telephone, msgCode, openId);
        return null;
    }

    @Override
    public String refreshToken(String token) {
        return jwtTokenUtil.refreshHeadToken(token);
    }

    //对输入的验证码进行校验
    private boolean verifyAuthCode(String authCode, String telephone, String openId) {
        if (StrUtil.isEmpty(authCode)) {
            return false;
        }
        String realAuthCode = memberCacheService.getAuthCode(telephone, authCode, openId);
        return authCode.equals(realAuthCode);
    }


    @Override
    public List<Map<String, Object>> getDailyIncreaseData(Date startDate, Date endDate, Integer vip) {

        return memberMapper.getDailyIncreaseData(startDate, endDate, vip);
    }
}
